home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / xvectors / vector0.03.c < prev    next >
C/C++ Source or Header  |  1995-11-05  |  10KB  |  352 lines

  1. /****************************************************************************/
  2. /*                                        */
  3. /*                3D-Rotaion Routines                    */
  4. /*                                        */
  5. /*  CrEatOr: LarZ SamuelssoN                      AD: 1993         */
  6. /*                                        */
  7. /*  Version 0.03: Removed a lot of comments. Read 'em in earlier versions.  */ 
  8. /*                                        */
  9. /****************************************************************************/
  10.  
  11. #include <X11/Xlib.h>    
  12. #include <X11/X.h>    
  13. #include <stdio.h>    
  14. #include <math.h>    
  15. #include <stdlib.h>    
  16.  
  17. #define    CORNERS 8    
  18. #define DIM    3    
  19. #define PTS    4    
  20. #define LSIZE    628    /* nr of entrys in the sine-table            */
  21.  
  22. typedef float   Base[ DIM ];
  23. typedef    float    Vob[ CORNERS ][ DIM ];
  24.  
  25. /* function prototypes                                */
  26.  
  27. void Cls(void);
  28. void Init(void);
  29. void Exit(void);
  30.  
  31. void SetCol(char *);
  32.  
  33. /* Yep... You're right... Something's different here (another speed-up)        */
  34.  
  35. void Rotate(Vob *, int *, int *, int *, int *, int *, int *, 
  36.         int, int, int, Base *, Base *, Base *, float *);
  37.  
  38. void DrawSOb(Vob *, Base, Base, Base, int, int, int, int);
  39. void ClearSOb(Vob *, Base, Base, Base, int, int, int, int);
  40. void DrawSolid(int, int, int, int, int, int, int, int, int, int);
  41.  
  42. Vob * Perspect(Vob *, int);
  43.  
  44. /* These are the variables set out to explore the unknown (X)                */
  45.  
  46. Display         *dpy;
  47. XPoint            mypoints[ PTS ];
  48. XColor             xcolour;
  49. GC             gc;
  50. XGCValues         xgcvalues;
  51. XSetWindowAttributes     xsetwattrs;
  52. int            scrn, pixel;
  53.  
  54. int main (void)
  55. {
  56.       int     cx = 850;    /*  Center of rotation (rootwindow coords)  */
  57.     int     cy = 830;
  58.  
  59.     int     wx = 0;        /*        Inital angles of the cube           */
  60.     int    wy = 0;        /* These will be used to hold the value of  */
  61.     int    wz = 0;        /*        the angle during rotation         */
  62.  
  63.     int     vx = wx + LSIZE/4;    /* wX are counters for sine    */ 
  64.     int     vy = wy + LSIZE/4;    /* vX are counters for cosine    */
  65.     int     vz = wz + LSIZE/4;
  66.  
  67.     int     xstep = 1;     /*       Step-angle used in rotation         */
  68.     int     ystep = 2;     /*                        */
  69.     int     zstep = 1;     /*     ( small step = smooth rotation )        */
  70.  
  71.     int     depth = 5;    /*            Perspective depth         */
  72.     int    scale = 40;    /*        Scaling factor (in pixels)        */
  73.  
  74.     /* This is our three base vectors                    */
  75.  
  76.     Base e1 = { 1, 0, 0 };
  77.     Base e2 = { 0, 1, 0 };
  78.     Base e3 = { 0, 0, 1 };
  79.  
  80.     /* This is the object we will be dealing with, hence, a cube.        */
  81.  
  82.     Vob     cube =
  83.     {
  84.         {  1,  1,  1 },
  85.         {  1, -1,  1 },
  86.         {  1, -1, -1 },
  87.         {  1,  1, -1 },
  88.         { -1,  1, -1 },
  89.         { -1,  1,  1 },
  90.         { -1, -1,  1 },
  91.         { -1, -1, -1 },
  92.      };
  93.  
  94.     Vob *    pos;        /* Holds the position of the cube's corners */
  95.                 /* during the calculations            */
  96.  
  97.         /*        precalculated sine-table        */
  98.  
  99.     float     sinT[ LSIZE ];
  100.     int     i;    
  101.  
  102.     for ( i=0; i < LSIZE; i++ ) sinT[i] = sin(0.01*i);
  103.  
  104.     Init( );
  105.     Cls( );
  106.  
  107.     pos = &cube;
  108.     while (4711)
  109.     {
  110.         ClearSOb( Perspect( pos, depth ), e1, e2, e3, 
  111.               scale, cx, cy, depth );     
  112.     
  113.         Rotate( pos, &wx, &wy, &wz, &vx, &vy, &vz, 
  114.             xstep, ystep, zstep, 
  115.             &e1, &e2, &e3, sinT );    
  116.  
  117.         DrawSOb( Perspect( pos, depth ), e1, e2, e3, 
  118.              scale, cx, cy, depth ); 
  119.     }
  120.  
  121.     Exit( );
  122.       return 0;
  123. }
  124.  
  125. void ClearSOb(Vob * em, Base e1, Base e2, Base e3, int s, int x, int y, int p)
  126. {
  127.     Vob v;
  128.     float num;
  129.     int i;
  130.  
  131.     for ( i=0; i<CORNERS; i++ )
  132.     {
  133.         v[i][0] = s*(*em)[i][0];
  134.         v[i][1] = s*(*em)[i][1];
  135.     }
  136.  
  137.     if (p) num = (float) 1/p;
  138.     else   num = 0;
  139.  
  140.     SetCol("black");
  141.     if ( e1[ DIM-1 ] > num )
  142.         DrawSolid(v[0][0], v[0][1], v[1][0], v[1][1], 
  143.               v[2][0], v[2][1], v[3][0], v[3][1], x, y);
  144.     if ( e1[ DIM-1 ] < -num )
  145.         DrawSolid(v[4][0], v[4][1], v[5][0], v[5][1], 
  146.               v[6][0], v[6][1], v[7][0], v[7][1], x, y);
  147.     if ( e2[ DIM-1 ] > num )
  148.         DrawSolid(v[0][0], v[0][1], v[3][0], v[3][1], 
  149.               v[4][0], v[4][1], v[5][0], v[5][1], x, y);
  150.     if ( e2[ DIM-1 ] < -num )
  151.         DrawSolid(v[1][0], v[1][1], v[2][0], v[2][1], 
  152.               v[7][0], v[7][1], v[6][0], v[6][1], x, y);
  153.     if ( e3[ DIM-1 ] > num )
  154.         DrawSolid(v[0][0], v[0][1], v[1][0], v[1][1], 
  155.               v[6][0], v[6][1], v[5][0], v[5][1], x, y);
  156.     if ( e3[ DIM-1 ] < -num )
  157.         DrawSolid(v[3][0], v[3][1], v[2][0], v[2][1], 
  158.               v[7][0], v[7][1], v[4][0], v[4][1], x, y);
  159. }
  160.  
  161. void DrawSOb(Vob * em, Base e1, Base e2, Base e3, int s, int x, int y, int p)
  162. {
  163.     Vob v;
  164.     float num;
  165.     int i;
  166.                   /* scaling */
  167.  
  168.     for ( i=0; i<CORNERS; i++ )
  169.     {
  170.         v[i][0] = s*(*em)[i][0];
  171.         v[i][1] = s*(*em)[i][1];
  172.     }
  173.  
  174.     if (p) num = (float) 1/p;
  175.     else   num = 0;
  176.  
  177.     /*        Time to fill those sides with color        */
  178.  
  179.     SetCol("blue");
  180.     if ( e1[ DIM-1 ] > num )
  181.         DrawSolid(v[0][0], v[0][1], v[1][0], v[1][1], 
  182.               v[2][0], v[2][1], v[3][0], v[3][1], x, y);
  183.     SetCol("blue");
  184.     if ( e1[ DIM-1 ] < -num )
  185.         DrawSolid(v[4][0], v[4][1], v[5][0], v[5][1], 
  186.               v[6][0], v[6][1], v[7][0], v[7][1], x, y);
  187.     SetCol("cornflower blue");
  188.     if ( e2[ DIM-1 ] > num )
  189.         DrawSolid(v[0][0], v[0][1], v[3][0], v[3][1], 
  190.               v[4][0], v[4][1], v[5][0], v[5][1], x, y);
  191.     SetCol("cornflower blue");
  192.     if ( e2[ DIM-1 ] < -num )
  193.         DrawSolid(v[1][0], v[1][1], v[2][0], v[2][1], 
  194.               v[7][0], v[7][1], v[6][0], v[6][1], x, y);
  195.     SetCol("darkslateblue");
  196.     if ( e3[ DIM-1 ] > num )
  197.         DrawSolid(v[0][0], v[0][1], v[1][0], v[1][1], 
  198.               v[6][0], v[6][1], v[5][0], v[5][1], x, y);
  199.     SetCol("darkslateblue");
  200.     if ( e3[ DIM-1 ] < -num )
  201.         DrawSolid(v[3][0], v[3][1], v[2][0], v[2][1], 
  202.               v[7][0], v[7][1], v[4][0], v[4][1], x, y);
  203. }
  204.  
  205. /* This is where the perspective is calculated.                    */
  206.  
  207. Vob * Perspect(Vob * em, int depth)
  208. {
  209.     Vob temp;
  210.     int i;    
  211.  
  212.     for ( i=0;i <CORNERS; i++ )
  213.     {
  214.         temp[i][0] = (*em)[i][0]*depth/(depth-(*em)[i][2]);
  215.         temp[i][1] = (*em)[i][1]*depth/(depth-(*em)[i][2]);
  216.     }
  217.     return &temp;
  218. }
  219.  
  220. /* I guess the main changes from v0.02 to v0.03 are in this function.        */
  221. /* In the previous version I needed 27 multiplications and some adds...     */
  222. /* If I instead of calculating each new position from the previous position */
  223. /* calculate everything from an initial position I will save some muls.        */
  224. /* This is also to prefer because it keeps the errors small... You might    */
  225. /* have noticed that the cube in the earlier versions grew larger or         */
  226. /* smaller with time, because of the error introduced in every new rotation */
  227. /* Using an initial position the error will always be the same.         */
  228. /* So, as in the earlier versions I use my three base vectors and rotate    */
  229. /* these. But now I gradually rotate these with increasing angles from the  */
  230. /* initial position. As sin( ) is a time-consuming function I had to create */
  231. /* a sine-table with precalcualted values to get the necessary speed.        */
  232. /* ( This is how it is done in asm also )                    */
  233. /* This roataion routine uses:                            */
  234. /*                     16 multiplications            */
  235. /*                     6 compares                */
  236. /*                    58 adds and subs            */
  237. /* I'll try to optimze even further...                        */
  238.  
  239. void Rotate(Vob * em, int * wx, int * wy, int * wz, 
  240.         int * vx, int * vy, int * vz, 
  241.         int sx, int sy, int sz, 
  242.         Base * e1, Base * e2, Base * e3, float * sinT)
  243. {
  244.     int i;
  245.  
  246.     /* This is e1, e2, e3 multiplied with the rotation matrix     */
  247.     /* ( yes, another one than the one in the earlier versions )    */
  248.  
  249.     (*e1)[0] = -sinT[*wz] * sinT[*wx] - sinT[*vz] * sinT[*wy] * sinT[*vx];
  250.       (*e1)[1] =  sinT[*vz] * sinT[*wx] - sinT[*wz] * sinT[*wy] * sinT[*vx];
  251.       (*e1)[2] =  sinT[*vy] * sinT[*vx];
  252.     (*e2)[0] = -sinT[*wz] * sinT[*vx] + sinT[*vz] * sinT[*wy] * sinT[*wx];
  253.         (*e2)[1] =  sinT[*vz] * sinT[*vx] + sinT[*wz] * sinT[*wy] * sinT[*wx];
  254.       (*e2)[2] = -sinT[*vy] * sinT[*wx];
  255.       (*e3)[0] =  sinT[*vz] * sinT[*vy];
  256.       (*e3)[1] =  sinT[*wz] * sinT[*vy];
  257.       (*e3)[2] =  sinT[*wy];
  258.  
  259.     /* Here we need to check the values of vX and wX, because our     */
  260.     /* table-array only has LSIZE positions.            */
  261.     /* Note that cos( x ) = sin( x + pi/2 )    and therefore we can    */
  262.     /* use just one table.                        */
  263.  
  264.     if ( *vx < LSIZE - 1 )        *vx = *vx + sx;
  265.     else                *vx = 0;
  266.     if ( *vy < LSIZE - 1 )        *vy = *vy + sy;
  267.     else                *vy = 0;
  268.     if ( *vz < LSIZE - 1 )        *vz = *vz + sz;
  269.     else                *vz = 0;
  270.     if ( *wx < LSIZE - 1 )         *wx = *wx + sx;
  271.     else                 *wx = 0;
  272.     if ( *wy < LSIZE - 1 )         *wy = *wy + sy;
  273.     else                 *wy = 0;
  274.     if ( *wz < LSIZE - 1 )         *wz = *wz + sz;
  275.     else                 *wz = 0;
  276.  
  277.     /* Now it's time to remember those inital coordinates        */
  278.     /* of our object. Here we express the coordinates of         */
  279.     /* the corners relative our base e1,e2,e3.              */
  280.  
  281.     for ( i=0; i<DIM; i++ )
  282.     {
  283.         (*em)[0][i] =   (*e1)[i] + (*e2)[i] + (*e3)[i];
  284.         (*em)[1][i] =   (*e1)[i] - (*e2)[i] + (*e3)[i];
  285.         (*em)[2][i] =   (*e1)[i] - (*e2)[i] - (*e3)[i];
  286.         (*em)[3][i] =   (*e1)[i] + (*e2)[i] - (*e3)[i];
  287.         (*em)[4][i] = - (*e1)[i] + (*e2)[i] - (*e3)[i];
  288.         (*em)[5][i] = - (*e1)[i] + (*e2)[i] + (*e3)[i];
  289.         (*em)[6][i] = - (*e1)[i] - (*e2)[i] + (*e3)[i];
  290.         (*em)[7][i] = - (*e1)[i] - (*e2)[i] - (*e3)[i];
  291.     }
  292. }
  293.  
  294. void DrawSolid(int x1, int y1, int x2, int y2, int x3, int y3, 
  295.            int x4, int y4, int ox, int oy)
  296. {
  297.     mypoints[0].x = ox + x1;
  298.     mypoints[0].y = oy + y1;
  299.     mypoints[1].x = ox + x2;
  300.     mypoints[1].y = oy + y2;
  301.     mypoints[2].x = ox + x3;
  302.     mypoints[2].y = oy + y3;
  303.     mypoints[3].x = ox + x4;
  304.     mypoints[3].y = oy + y4;
  305.  
  306.     XFillPolygon(dpy, RootWindow(dpy, scrn), gc, mypoints, PTS, 
  307.              Convex, CoordModeOrigin);
  308. }
  309.  
  310. void SetCol(char * str)
  311. {
  312.       if (XParseColor (dpy, DefaultColormap(dpy,scrn), str, &xcolour))
  313.             if (XAllocColor (dpy, DefaultColormap(dpy,scrn), &xcolour))
  314.             xgcvalues.foreground = xcolour.pixel;
  315.     XChangeGC (dpy,gc,GCForeground, &xgcvalues);
  316. }
  317.  
  318. void Cls(void)
  319. {
  320.         XClearWindow(dpy,RootWindow(dpy,scrn));
  321. }
  322.  
  323. void Init(void)
  324. {
  325.     if (!(dpy = XOpenDisplay (NULL))) 
  326.        {
  327.               fprintf (stderr, "Cannot open display.\n");
  328.               exit(1);
  329.         }
  330.       scrn                 = DefaultScreen(dpy);
  331.     xsetwattrs.backing_store     = Always;
  332.      xsetwattrs.background_pixel     = BlackPixel(dpy,scrn);
  333.     pixel                 = WhitePixel(dpy,scrn);
  334.  
  335.       XChangeWindowAttributes(dpy,RootWindow(dpy,scrn),
  336.                  CWBackingStore|CWBackPixel,
  337.                 &xsetwattrs);
  338.       if (XParseColor (dpy, DefaultColormap(dpy,scrn), "khaki2", &xcolour))
  339.             if (XAllocColor (dpy, DefaultColormap(dpy,scrn), &xcolour))
  340.                   pixel = xcolour.pixel;
  341.  
  342.       gc = XCreateGC (dpy, RootWindow(dpy,scrn),0,NULL);
  343. }
  344.     
  345. void Exit(void)
  346. {
  347.     XFlush (dpy);
  348. }
  349.  
  350.  
  351.  
  352.